/**
 *
 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either 
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public 
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 * 
 **/
package lucee.runtime.tag;

import java.io.IOException;
import java.io.Writer;

import lucee.commons.lang.StringUtil;
import lucee.runtime.exp.ApplicationException;
import lucee.runtime.exp.PageRuntimeException;
import lucee.runtime.ext.tag.BodyTagTryCatchFinallyImpl;
import lucee.runtime.op.Caster;
import lucee.runtime.writer.CFMLWriter;
import lucee.runtime.writer.WhiteSpaceWriter;

/**
 * Suppresses extra white space and other output, produced by CFML within the tag's scope.
 *
 *
 *
 **/
public final class ProcessingDirective extends BodyTagTryCatchFinallyImpl {

	/**
	 * A string literal; the character encoding to use to read the page. The value may be enclosed in
	 * single or double quotation marks, or none.
	 */
	// private String pageencoding=null;

	private Boolean suppresswhitespace;
	private boolean hasBody;

	@Override
	public void release() {
		super.release();
		// pageencoding=null;
		suppresswhitespace = null;
	}

	/**
	 * constructor for the tag class
	 **/
	public ProcessingDirective() {
	}

	/**
	 * set the value pageencoding A string literal; the character encoding to use to read the page. The
	 * value may be enclosed in single or double quotation marks, or none.
	 * 
	 * @param pageencoding value to set
	 **/
	public void setPageencoding(String pageencoding) {
	}

	public void setExecutionlog(boolean executionlog) {
	}

	public void setPreservecase(boolean b) {
	}

	/**
	 * set the value suppresswhitespace Boolean indicating whether to suppress the white space and other
	 * output generated by the CFML tags within the cfprocessingdirective block.
	 * 
	 * @param suppresswhitespace value to set
	 **/
	public void setSuppresswhitespace(boolean suppresswhitespace) {
		this.suppresswhitespace = Caster.toBoolean(suppresswhitespace);
	}

	@Override
	public int doStartTag() throws ApplicationException {
		if (suppresswhitespace != null && !hasBody) {
			throw new ApplicationException("To suppress whitespace, an end tag [cfprocessingdirective] is also required");
		}
		if (suppresswhitespace != null) return EVAL_BODY_BUFFERED;
		return EVAL_BODY_INCLUDE;
	}

	@Override
	public void doInitBody() {
	}

	@Override
	public int doAfterBody() {
		return SKIP_BODY;
	}

	/**
	 * sets if tag has a body or not
	 * 
	 * @param hasBody
	 */
	public void hasBody(boolean hasBody) {
		this.hasBody = hasBody;
	}

	@Override
	public void doFinally() {
		if (suppresswhitespace != null) {
			try {
				/* JspWriter */Writer out = pageContext.getOut();
				if (suppresswhitespace.booleanValue()) {
					if (out instanceof WhiteSpaceWriter) out.write(bodyContent.getString());
					else out.write(StringUtil.suppressWhiteSpace(bodyContent.getString()));
				}
				else {
					if (out instanceof CFMLWriter) {
						((CFMLWriter) out).writeRaw(bodyContent.getString());
					}
					else out.write(bodyContent.getString());
				}
			}
			catch (IOException e) {
				throw new PageRuntimeException(Caster.toPageException(e));
			}
		}
	}
}
